Projekt_CV

Tematyka zadania

Celem tego projektu jest zbudowanie modelu konwolucyjnej sieci neuronowej służącej do klasyfikacji dzieł sztuki ze względu na gatunek (11 etykiet) oraz stylów malarskich (27 etykiet).

Zbiór danych którym posłużyliśmy się do trenowania modeli jest WikiArt zawierający ponad 84 tysiące różnych obrazów. Zbiór ten funkcjonuje w otwartym dostępie i jest darmowy do niekomercyjnego użytku.

Największą trudność zadania stanowi fakt że klasyfikacja obrazów jest zadaniem o charakterze abstrakcyjnym w zestawieniu z klasyfikacją przedmitów, ludzi lub zwirząt.

Dodatkowo specyfika zadania uniemożliwa wykorzystanie augmentacji (dla danego obrazu możliwy jest tylko oryginalny sposób reprezentacji zgodny z projektem artysty).

Klasyfikacja gatunku obrazu

Każdy z obrazów posiada etykietę wskazującą na gatunek obrazu:

  • 0 - Malarstwo abstrakcyjne

  • 1 - Pejzaż miejski

  • 2 - Malarstwo rodzajowe

  • 3 - Ilustracja

  • 4 - Pejzaż

  • 5 - Malarstwo nagie

  • 6 - Portret

  • 7 - Malarstwo religijne

  • 8 - Szkic

  • 9 - Martwa natura

  • 10 - Gatunek nieznany

Pierwszy projekt sieci

Pierwsza testowana przez nas architekutra sieci jest stosunkowo prosta ponieważ składa się jedynie z 4 warstw konwolucyjnych i max poolingowych ze stosunkowo niewielką ilością filtrów.

Kod
model <- keras_model_sequential() %>%
  layer_conv_2d(filters = 32, kernel_size = c(3, 3), activation = "relu",
                input_shape = c(150, 150, 3)) %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_conv_2d(filters = 64, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_flatten() %>%
  layer_dense(units = 512, activation = "relu") %>%
  layer_dense(units = 11, activation = "softmax")
Model: "sequential"
________________________________________________________________________________
Layer (type)                        Output Shape                    Param #     
================================================================================
conv2d_3 (Conv2D)                   (None, 148, 148, 32)            896         
________________________________________________________________________________
max_pooling2d_3 (MaxPooling2D)      (None, 74, 74, 32)              0           
________________________________________________________________________________
conv2d_2 (Conv2D)                   (None, 72, 72, 64)              18496       
________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)      (None, 36, 36, 64)              0           
________________________________________________________________________________
conv2d_1 (Conv2D)                   (None, 34, 34, 128)             73856       
________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)      (None, 17, 17, 128)             0           
________________________________________________________________________________
conv2d (Conv2D)                     (None, 15, 15, 128)             147584      
________________________________________________________________________________
max_pooling2d (MaxPooling2D)        (None, 7, 7, 128)               0           
________________________________________________________________________________
flatten (Flatten)                   (None, 6272)                    0           
________________________________________________________________________________
dense_1 (Dense)                     (None, 512)                     3211776     
________________________________________________________________________________
dense (Dense)                       (None, 11)                      5643        
================================================================================
Total params: 3,458,251
Trainable params: 3,458,251
Non-trainable params: 0
________________________________________________________________________________

Szkolenie w każdej epoce odbywało się na 3200 obrazkach oraz walidacja była przeprowadzana na 1600 obrazkach.

Funkcją optymalizującą był “Adam” oraz zastosowane zostały następujące callbacki:

  • Zapisywanie modelu po każdej epoce

  • Przerwanie procesu uczenia jeżeli celność nie poprawi się na zbiorze walidacyjnym po 5 epokach

Przy tej strukturze sieć szkoliła się przez 28 epok, kończąc proces uczenia przez zastosowanie callbacków ze względu na brak poprawy celności na zbiorze walidacyjnym.

Pierwsza sieć

Widać że nastąpiło zjawisko przeuczenia. Najwyższą celnością na zbiorze walidacyjnym było ~45%.

Drugi projekt sieci

Druga architektura składa się z większej liczby warstw konwolucyjnych oraz większej ilości filtrów. Dodatkowo tym razem dodaliśmy warstwy dropout’ów w celu redukcji przeuczenia sieci.

Kod
model <- keras_model_sequential() %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = "relu",
                input_shape = c(150, 150, 3)) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.2) %>%
  layer_conv_2d(filters = 64, kernel_size = c(3, 3), activation = "relu") %>%
  layer_conv_2d(filters = 64, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.3) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = "relu") %>%
  layer_conv_2d(filters = 32, kernel_size = c(3, 3), activation = "relu") %>%
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.3) %>% 
  layer_flatten() %>%
  layer_dense(units = 256, activation = "relu") %>%
  layer_dense(units = 54, activation = "relu") %>%
  layer_dropout(rate = 0.5) %>%
  layer_dense(units = 11, activation = "softmax")
Model: "sequential_1"
________________________________________________________________________________
Layer (type)                        Output Shape                    Param #     
================================================================================
conv2d_9 (Conv2D)                   (None, 148, 148, 128)           3584        
________________________________________________________________________________
conv2d_8 (Conv2D)                   (None, 146, 146, 128)           147584      
________________________________________________________________________________
max_pooling2d_6 (MaxPooling2D)      (None, 73, 73, 128)             0           
________________________________________________________________________________
dropout_3 (Dropout)                 (None, 73, 73, 128)             0           
________________________________________________________________________________
conv2d_7 (Conv2D)                   (None, 71, 71, 64)              73792       
________________________________________________________________________________
conv2d_6 (Conv2D)                   (None, 69, 69, 64)              36928       
________________________________________________________________________________
max_pooling2d_5 (MaxPooling2D)      (None, 34, 34, 64)              0           
________________________________________________________________________________
dropout_2 (Dropout)                 (None, 34, 34, 64)              0           
________________________________________________________________________________
conv2d_5 (Conv2D)                   (None, 32, 32, 128)             73856       
________________________________________________________________________________
conv2d_4 (Conv2D)                   (None, 30, 30, 32)              36896       
________________________________________________________________________________
max_pooling2d_4 (MaxPooling2D)      (None, 15, 15, 32)              0           
________________________________________________________________________________
dropout_1 (Dropout)                 (None, 15, 15, 32)              0           
________________________________________________________________________________
flatten_1 (Flatten)                 (None, 7200)                    0           
________________________________________________________________________________
dense_4 (Dense)                     (None, 256)                     1843456     
________________________________________________________________________________
dense_3 (Dense)                     (None, 54)                      13878       
________________________________________________________________________________
dropout (Dropout)                   (None, 54)                      0           
________________________________________________________________________________
dense_2 (Dense)                     (None, 11)                      605         
================================================================================
Total params: 2,230,579
Trainable params: 2,230,579
Non-trainable params: 0
________________________________________________________________________________

Uczenie tym razem odbywało się na 51200 obrazach w epoce, a następnie model walidowany był na 12800 obrazach.

Funkcją optymalizującą również był “Adam” oraz zastosowane były te same callbacki co przy wcześniejszej architekturze.

Druga sieć

Niestety także i przy tej architekturze nastąpiło zjawisko przeuczenia (nawet szybciej niż w przypadku sieci poprzedniej) osiągając accuracy maksymalnie na poziomie 0.45.

Trzeci projekt sieci

Tym razem zdecydowaliśmy się użyć wcześniej przeszkolonej sieci ResNet jako części konwolucyjnej. Ze względu na ograniczone zasoby obliczeniowe użyliśmy wersji ResNet50.

ResNet50 to wariant modelu ResNet, który składa się z 48 warstw konwolucyjnych, jednej warstwy MaxPool i jednej warstwy Average Pool. ResNet został zaprojektowany w celu dodawania większej liczby warstw konwolucyjnych do sieci CNN, bez napotkania problemu zanikającego gradientu, za pomocą koncepcji połączeń rezydualnych.

conv_base <- application_resnet50(
  weights = "imagenet",
  include_top = F,
  input_shape = c(224,224,3)
)
freeze_weights(conv_base)
unfreeze_weights(conv_base, from = "conv5_block3_2_conv")

Odmrażamy dwa ostatnie bloki konwolucyjne i normalizujące partię w celu dostrojenia sieci do naszego zadania.

Kod
model <- keras_model_sequential() %>%
  conv_base %>%
  layer_flatten() %>%
  layer_dense(units = 512, activation = "relu") %>%
  layer_dense(units = 11, activation = "softmax")
Model: "sequential_2"
_____________________________________________________________________
Layer (type)                   Output Shape               Param #    
=====================================================================
resnet50 (Functional)          (None, 7, 7, 2048)         23587712   
_____________________________________________________________________
flatten_2 (Flatten)            (None, 100352)             0          
_____________________________________________________________________
dense_6 (Dense)                (None, 512)                51380736   
_____________________________________________________________________
dense_5 (Dense)                (None, 11)                 5643       
=====================================================================
Total params: 74,974,091
Trainable params: 54,801,931
Non-trainable params: 20,172,160
_____________________________________________________________________

Sieć uczona była na pełnym zbiorze treningowym przy użyciu optimizera “Adam” i tych samch callbacków co przy poprzednich architekturach.

Trzecia sieć

W tym przypadku zjawisko przeuczenia nastąpiło nawet szybiciej niż przy poprzednich architekturach.

Czwarty projekt sieci

Kod
model <- keras_model_sequential() %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3),
                input_shape = c(224, 224, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.2) %>% 
  layer_conv_2d(filters = 64, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.3) %>% 
  layer_conv_2d(filters = 32, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_flatten() %>%
  layer_dropout(rate = 0.5) %>% 
  layer_dense(units = 512, activation = "relu") %>%
  layer_activity_regularization(l2 = 0.001) %>% 
  layer_dense(units = 11, activation = "softmax")
Model: "sequential_3"
________________________________________________________________________________
Layer (type)                        Output Shape                    Param #     
================================================================================
conv2d_13 (Conv2D)                  (None, 222, 222, 128)           3584        
________________________________________________________________________________
leaky_re_lu_3 (LeakyReLU)           (None, 222, 222, 128)           0           
________________________________________________________________________________
max_pooling2d_10 (MaxPooling2D)     (None, 111, 111, 128)           0           
________________________________________________________________________________
conv2d_12 (Conv2D)                  (None, 109, 109, 128)           147584      
________________________________________________________________________________
leaky_re_lu_2 (LeakyReLU)           (None, 109, 109, 128)           0           
________________________________________________________________________________
max_pooling2d_9 (MaxPooling2D)      (None, 54, 54, 128)             0           
________________________________________________________________________________
dropout_6 (Dropout)                 (None, 54, 54, 128)             0           
________________________________________________________________________________
conv2d_11 (Conv2D)                  (None, 52, 52, 64)              73792       
________________________________________________________________________________
leaky_re_lu_1 (LeakyReLU)           (None, 52, 52, 64)              0           
________________________________________________________________________________
max_pooling2d_8 (MaxPooling2D)      (None, 26, 26, 64)              0           
________________________________________________________________________________
dropout_5 (Dropout)                 (None, 26, 26, 64)              0           
________________________________________________________________________________
conv2d_10 (Conv2D)                  (None, 24, 24, 32)              18464       
________________________________________________________________________________
leaky_re_lu (LeakyReLU)             (None, 24, 24, 32)              0           
________________________________________________________________________________
max_pooling2d_7 (MaxPooling2D)      (None, 12, 12, 32)              0           
________________________________________________________________________________
flatten_3 (Flatten)                 (None, 4608)                    0           
________________________________________________________________________________
dropout_4 (Dropout)                 (None, 4608)                    0           
________________________________________________________________________________
dense_8 (Dense)                     (None, 512)                     2359808     
________________________________________________________________________________
activity_regularization (ActivityRe (None, 512)                     0           
________________________________________________________________________________
dense_7 (Dense)                     (None, 11)                      5643        
================================================================================
Total params: 2,608,875
Trainable params: 2,608,875
Non-trainable params: 0
________________________________________________________________________________

Ze względu na fakt że pierwsza architektura pomimo najprostrzej struktury dawała relatywnie najlepsze wyniki zdecydowaliśmy się do niej wrócić z modyfikacjami w postaci regurlaryzacji oraz funkcji aktywacji w postaci “leaky reLU”.

Czwarta sieć

Podczas uczenia callbacki ustawione były na:

  • Zapisywanie modelu po każdej epoce

  • Przerwanie procesu uczenia jeżeli funkcja straty nie poprawi się na zbiorze walidacyjnym po 5 epokach

  • Obniżenie learning rate jeżeli funkcja straty nie poprawi się na zbiorze walidacyjnym po 3 epokach

W porównaniu do wszystkich poprzednich struktur ta wypada najlepiej zarówno na zbiorze uczącym (~67% celności) jak i walidacyjnym (~47% celności).

Niestety pomimo lepszych wyników uczenia oraz obniżenia learning rate (widać że za pierwszym razem poprawił celność) model jest przeuczony.

Piąty projekt sieci

Pomimo faktu, że modele które wykorzystywały wcześniej przetrenowaną sieć konwolucyjną ResNet50, okazały się być gorsze nawet od prostych struktur. Zdecydowaliśmy się użyć nowszej struktury DensNet121, wykorzystującej bardziej zaawansowane połączenia resztowe.

ResNet vs DensNet

Zdecydowaliśmy się na DensNet121 z tego względu iż jest to najmniejsza struktura z architektur DensNet co jest ważne przy ograniczonych zasobach sprzętowych.

Tym razem uznaliśmy jednak, że abstrakcyjny charakter zadania wymaga przeszkolenia całej struktury na nowo, ponieważ wzorce wyuczone na zbiorze “Imagenet” mogą nie dawać zadowalających wyników.

conv_base <- application_densenet121(
  weights = NULL,
  include_top = TRUE,
  classes = 11,
  input_shape = c(224, 224, 3)
)

model <- conv_base

Piąta sieć

W tym przypadku architektura ta okazała się być najlepsza z wszystkich dotychczasowych osiągając blisko 60% na zbiorze walidacyjnym.

Szósty projekt sieci

W tym podejściu postanowiliśmy zastosować predefiniowaną sieć NASNetMobile ze względu na jej niewielki rozmiar oraz fakt że jak na razie gotowe architektury, uczone od początku (losowo inicjalizowane wagi) dawały najlepsze wyniki.

conv_base <- application_nasnetmobile(
  weights = NULL,
  include_top = TRUE,
  classes = 11,
  input_shape = c(224, 224, 3)
)

model <- conv_base

Szósta siec

Wyniki okazały się być nieco gorsze od poprzedniej architektury oparej na DenNet121 poniważ jest to około 55% celności na zbiorze walidacyjnym. Dodatkowo w tym przypadku efekt przeuczenia jest mniejszy niż w poprzedniej architekturze więc daje to potencjał żeby jeszcze ją poprawić.

Klasyfikacja stylu obrazu

  • 0 - Abstrakcjonizm ekspresyjny

  • 1 - Malowidło akcji

  • 2 - Kubizm anlityczny

  • 3 - Secesja

  • 4 - Barok

  • 5 - Malarstwo barwnych płaszczyzn

  • 6 - Realizm współczesny

  • 7 - Kubizm

  • 8 - Wczesny Renesans

  • 9 - Ekspresjonizm

  • 10 - Fowizm

  • 11 - Późny renesans

  • 12 - Impresjonizm

  • 13 - Manieryzm późnego renesansu

  • 14 - Minimalizm

  • 15 - Prymitywizm (Naïve art)

  • 16 - Nowy realizm

  • 17 - Renesans północny

  • 18 - Puentylizm

  • 19 - Pop-art

  • 20 - Postimpresjonizm

  • 21 - Realizm

  • 22 - Rokoko

  • 23 - Romantyzm

  • 24 - Symbolizm

  • 25 - Kubizm syntetyczny

  • 26 - Ukiyo-e

  • 27 - Styl nieznany

Pierwszy projekt sieci

Pierwszą architekturę sieci do rozpoznawania styli malarstwa postanowiliśmy oprzeć o wcześniej wyuczoną sieć ResNet50 z odmrożonymi dwoma blokami konwolucji.

W tym przypadku zdecydowaliśmy się na mniejszy blok gęsty względem architektury do rozpoznawania gatunków.

Kod
conv_base <- application_resnet50(
  weights = "imagenet",
  include_top = F,
  input_shape = c(224,224,3)
)

model <- keras_model_sequential() %>%
  conv_base %>%
  layer_flatten() %>%
  layer_dense(units = 256, activation = "relu") %>%
  layer_dense(units = 27, activation = "softmax")
Model: "sequential_4"
_____________________________________________________________________
Layer (type)                   Output Shape               Param #    
=====================================================================
resnet50 (Functional)          (None, 7, 7, 2048)         23587712   
_____________________________________________________________________
flatten_4 (Flatten)            (None, 100352)             0          
_____________________________________________________________________
dense_10 (Dense)               (None, 256)                25690368   
_____________________________________________________________________
dense_9 (Dense)                (None, 27)                 6939       
=====================================================================
Total params: 49,285,019
Trainable params: 49,231,899
Non-trainable params: 53,120
_____________________________________________________________________

Podczas uczenia callbacki ustawione były na:

  • Zapisywanie modelu po każdej epoce

  • Przerwanie procesu uczenia jeżeli funkcja straty nie poprawi się na zbiorze walidacyjnym po 8 epokach

  • Obniżenie learning rate jeżeli funkcja straty nie poprawi się na zbiorze walidacyjnym po 4 epokach

Niestety proces uczenia został przerwany ze względu na limity platformy kaggle (kompilacja notatnika osiągnęła 12h) z tego względu dysponujemy jedynie logami dla rezultatów 27 epoki

loss: 2.1323 - acc: 0.3101 - val_loss: 2.2895 - val_acc: 0.2795 - lr: 1.0000e-06

Drugi projekt sieci

Jako drugą architekturę sieci postanowiliśmy wykorzystać czwartą architekturę zaproponowaną do klasyfikacji gatunków ze względu na fakt że osiągała ona najlepsze wyniki.

Kod
model <- keras_model_sequential() %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3),
                input_shape = c(224, 224, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_conv_2d(filters = 128, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.2) %>% 
  layer_conv_2d(filters = 64, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_dropout(rate = 0.3) %>% 
  layer_conv_2d(filters = 32, kernel_size = c(3, 3)) %>%
  layer_activation_leaky_relu(alpha = 0.1) %>% 
  layer_max_pooling_2d(pool_size = c(2, 2)) %>%
  layer_flatten() %>%
  layer_dropout(rate = 0.5) %>% 
  layer_dense(units = 512, activation = "relu") %>%
  layer_activity_regularization(l2 = 0.001) %>% 
  layer_dense(units = 27, activation = "softmax")
Model: "sequential_5"
________________________________________________________________________________
Layer (type)                        Output Shape                    Param #     
================================================================================
conv2d_17 (Conv2D)                  (None, 222, 222, 128)           3584        
________________________________________________________________________________
leaky_re_lu_7 (LeakyReLU)           (None, 222, 222, 128)           0           
________________________________________________________________________________
max_pooling2d_14 (MaxPooling2D)     (None, 111, 111, 128)           0           
________________________________________________________________________________
conv2d_16 (Conv2D)                  (None, 109, 109, 128)           147584      
________________________________________________________________________________
leaky_re_lu_6 (LeakyReLU)           (None, 109, 109, 128)           0           
________________________________________________________________________________
max_pooling2d_13 (MaxPooling2D)     (None, 54, 54, 128)             0           
________________________________________________________________________________
dropout_9 (Dropout)                 (None, 54, 54, 128)             0           
________________________________________________________________________________
conv2d_15 (Conv2D)                  (None, 52, 52, 64)              73792       
________________________________________________________________________________
leaky_re_lu_5 (LeakyReLU)           (None, 52, 52, 64)              0           
________________________________________________________________________________
max_pooling2d_12 (MaxPooling2D)     (None, 26, 26, 64)              0           
________________________________________________________________________________
dropout_8 (Dropout)                 (None, 26, 26, 64)              0           
________________________________________________________________________________
conv2d_14 (Conv2D)                  (None, 24, 24, 32)              18464       
________________________________________________________________________________
leaky_re_lu_4 (LeakyReLU)           (None, 24, 24, 32)              0           
________________________________________________________________________________
max_pooling2d_11 (MaxPooling2D)     (None, 12, 12, 32)              0           
________________________________________________________________________________
flatten_5 (Flatten)                 (None, 4608)                    0           
________________________________________________________________________________
dropout_7 (Dropout)                 (None, 4608)                    0           
________________________________________________________________________________
dense_12 (Dense)                    (None, 512)                     2359808     
________________________________________________________________________________
activity_regularization_1 (Activity (None, 512)                     0           
________________________________________________________________________________
dense_11 (Dense)                    (None, 27)                      13851       
================================================================================
Total params: 2,617,083
Trainable params: 2,617,083
Non-trainable params: 0
________________________________________________________________________________

Druga sieć

Pomimo faktu, że i przy tej strukturze sieci następuje przeuczenie osiąga ona taki sam wynik na zbiorze uczącym po 3 epokach co struktura oparta na ResNet50 osiągnęła po 27.

Trzeci projekt sieci

Zachęceni wynikami uzyskanymi na gatunkach z szkolonej od początku architektury DensNet121 postawnowiliśmy użyć jej również do klasyfikacji styli.

conv_base <- application_densenet121(
  weights = NULL,
  include_top = TRUE,
  classes = 11,
  input_shape = c(224, 224, 3)
)

model <- conv_base

Trzecia sieć

Decyzja ta okazała się być trafiona. Po raz pierwszy udało się osiągnąć celnośc powyżej 50% (~52%).

Ewaluacja modeli

Gatunki

Gatunki

model

loss

accuracy

top3

top5

Arch1

1.535

0.456

0.783

0.913

Arch2

1.645

0.433

0.773

0.905

ResNet50

1.690

0.425

0.765

0.903

Arch3

1.595

0.483

0.772

0.907

DensNet121

1.240

0.566

0.792

0.917

NASNetMobile

1.262

0.565

0.803

0.922

W przypadku modeli przeznaczonych do klasyfikacji gatunków malarstwa najlepiej sprawdziły się architektury DenNet121 i NASNetMobile trenowane od początku. Obie sieci osiągają bardzo zbliżone wyniki z niewielką przewagą na korzyść DenNet ze względu na funkcję straty.

Najgorszą architekturą okzał się ResNet50 wcześniej przetrenowany na zbiorze “Imagenet” z odmrożonymi dwoma blokami konwolucyjnymi. Przypuszczać można że spowodowane jest to faktem iż charakter zadania jest bardziej abstrakcyjny niż klasy zawarte w zbiorze uczącym tej architektury.

Ciekawe jest, że pierwsza architektura, będąca zarazem najprostrsza i ucząca się na niewielkim wycinku zbioru uczącego osiągneła lepsze wyniki niż struktury bardziej złożone.

Warto w tym przypadku nadmienić że miara top 5 przy 11 kategoriach nie jest aż tak dobrym odzwierciedleniem jakości klasyfkiacji. Najważniejsze dalej będzie accuracy oraz top 3.

W przypadku miary top 3 dwa ostatnie modele osiągają zadowalające wyniki na poziomie ~80%

Style

Style

model

loss

accuracy

top3

top5

ResNet50

2.295

0.275

0.770

0.892

Arch3

2.189

0.370

0.755

0.880

DensNet121

1.593

0.495

0.758

0.881

W przypadku klasyfikacji styli malarskich wyniki są bardzo podobne do tych obserwowanych przy gatunkach. Najgorzej wypada wcześniej nauczona sieć ResNet50 osiągając bardzo niskie accuracy 27,5% i o dziwo najwyższe wyniki na miarach top 3 i top 5.

Jeżeli chodzi o funkcje straty i accuracy zdecydowanie najlepiej wypadła architektura DensNet121 osiągając prawie 50% celności.

W tym przypadku metryka top 5 jest znacznie bardziej miarodajna ze względu na fakt że tym razem zadanie ma 27 kategorii.

Decydując się na model oparty na DensNet121 jesteśmy w stanie osiągnać zadowaljący wynik 75% przy metryce top 3.

Predykcja

Camille Corot “large sharecropping farm”

\[ \text{Gatunek: Pejzaż} \qquad \text{Styl: Realizm} \]

Gatunek

Prawdop.

Martwa natura

30.15

Malarstwo rodzajowe

23.14

Szkic

16.23

Pejzaż

8.30

Ilustracja

6.16

Styl

Prawdop.

Minimalizm

34.59

Nowy realizm

34.34

Barok

19.39

Realizm

8.76

Kubizm

2.55

Vincent Van Gogh “view on the singel in amsterdam”

\[ \text{Gatunek: Pejzaż miejski} \qquad \text{Styl: Realizm} \]

Gatunek

Prawdop.

Malarstwo nagie

51.29

Malarstwo rodzajowe

27.10

Ilustracja

8.45

Malarstwo abstrakcyjne

7.64

Malarstwo religijne

1.85

Styl

Prawdop.

Minimalizm

100

Barok

0

Nowy realizm

0

Wczesny Renesans

0

Kubizm

0

Katsushika Hokusai “Tsukada island in the Musashi province”

\[ \text{Gatunek: Gatunek nieznany} \qquad \text{Styl: Ukiyo-e} \]

Gatunek

Prawdop.

Szkic

57.66

Malarstwo rodzajowe

19.14

Ilustracja

18.38

Malarstwo religijne

1.71

Pejzaż

1.24

Styl

Prawdop.

Minimalizm

46.56

Nowy realizm

19.95

Ekspresjonizm

7.91

Ukiyo-e

7.86

Kubizm

5.61

Vasily Perov “sermon in a village”

\[ \text{Gatunek: Malarstwo rodzajowe} \qquad \text{Styl: Realizm} \]

Gatunek

Prawdop.

Malarstwo nagie

97.85

Pejzaż miejski

1.75

Ilustracja

0.28

Malarstwo rodzajowe

0.09

Martwa natura

0.03

Styl

Prawdop.

Pop-art

93.54

Późny renesans

3.74

Ukiyo-e

1.55

Abstrakcjonizm ekspresyjny

0.52

Renesans północny

0.28

Orest Kiprensky “athena”

\[ \text{Gatunek: Szkic} \qquad \text{Styl: Romantyzm} \]

Gatunek

Prawdop.

Pejzaż miejski

80.77

Malarstwo nagie

18.26

Malarstwo rodzajowe

0.76

Ilustracja

0.19

Martwa natura

0.01

Styl

Prawdop.

Minimalizm

93.66

Realizm

3.02

Nowy realizm

1.68

Prymitywizm (Naïve art)

1.37

Renesans północny

0.10

Linki do prac

Budowa modeli: https://www.kaggle.com/code/datachad/projekt-cv

Ewaluacja modeli: https://www.kaggle.com/code/datachad/projekt-cv-eval

Repozytorium: https://github.com/Chajf/Projekt_ComputerVision